﻿package net.molchat.android.core;


import android.util.Log;


// ============================================================= Генератор тиков
public class Tick extends Thread {

//=================================================================== Переменные

private boolean fRun = true; // Флаг времени работы среды
private boolean fPause = true; // Флаг паузы
private boolean fUpdated; // Флаг обновления времени ожидания
private TickEvent event; // Обработчик события
private int delay = 1000; // Пауза между тиками, мс
private long nextTick; // Время следующего вызова


//================================================================ Инициализация
public Tick(int delay, TickEvent handler) {

	Log.v("Tick.init", "===== delay = " + delay);
	this.delay = delay;
	this.event = handler;
	this.start();
}


// ======================================================================= Пауза
public void pauseTick() {

	//		Log.v("Tick.pauseTick", "pauseTick");

	synchronized (this) {
		fPause = true;
	}
}


//================================================================== Продолжение
public void resumeTick() {

	//		Log.v("Tick.resumeTick", "resumeTick");

	synchronized (this) {
		this.update();
		fPause = false;
		this.notifyAll();
	}
}


//============================================================ Остановка и выход
public void exit() {

	Log.v("Tick.exit", "Останов");
	fRun = false;
	event = null;
	fPause = false;

	synchronized (this) {
		this.notifyAll();
	}
}


//====================================================== Обновить время ожидания
public void update() {

	nextTick = System.currentTimeMillis() + delay;
	fUpdated = true;
}


//=============================================================== Среда анимации
public void run() {

	long sleepTime;
	long curTime = 0;

	//Log.v("Tick.run", who + " Запуск");
	try {

		// Начальная пауза
		synchronized (this) {
			while (fPause) {
				this.wait();
			}
		}

		// Основной цикл
		while (fRun) {

			do {
				fUpdated = false;
				curTime = System.currentTimeMillis();
				sleepTime = nextTick - curTime;
				if (sleepTime > 0) {
					nextTick += delay;
					sleep(sleepTime);
				} else {
					nextTick = curTime + delay;
				}
			} while (fUpdated);

			if (fPause) {
				synchronized (this) {
					while (fPause) {
						this.wait();
					}
				}
			}

			//			Log.v("Tick.run", "tick");

			// TODO Сделать метод tick типом void
			event.tick();
		} // while
	} catch (InterruptedException e) {
		//Log.v("Tick.run", "Завершаем работу ", e);
	} catch (Exception e) {
		Log.e("Tick.run", "unexpected", e);
	}

	Log.v("Tick.run", "Среда анимации завершена");
	event = null;
}
}
